﻿using System;
using System.Linq;
using System.Text;
using System.Collections.Generic;
using System.Runtime.Serialization;

namespace Working.Domínio.RecursosHumanos
{
  [Serializable]
  public class Funcionário: Pessoa
  {
    #region Construtores ---------------------------------------------------------

    public Funcionário(string nome, DateTime dataDeNascimento)
      : base(nome, dataDeNascimento) { }

    public Funcionário(string nome, DateTime dataDeNascimento, string númeroDoCpf)
      : this(nome, dataDeNascimento)
    {
      this.Cpf = númeroDoCpf;
    }

    protected Funcionário(SerializationInfo info, StreamingContext context)
      : base(info, context)
    {
      this.BeginLoad();
      try
      {
        this.salário = info.GetDecimal("Salário");
        this.carteiraDeTrabalho = (CarteiraDeTrabalho)info.GetValue("CarteiraDeTrabalho", typeof(CarteiraDeTrabalho));
        this.pisPasep = info.GetString("PisPasep");
        this.dataDeAdmissão = info.GetDateTime("DataDeAdmissão");
        this.dataDeDemissão = info.GetDateTime("DataDeDemissão");
      }
      finally
      {
        this.EndLoad();
      }
    }


    #endregion


    #region Propriedades ---------------------------------------------------------


    public override string Cpf
    {
      get { return base.Cpf; }
      set
      {
        if(value == null)
          throw new WorkingException("Cpf inválido.");

        base.Cpf = value;
      }
    }

    public CarteiraDeTrabalho CarteiraDeTrabalho
    {
      get { return carteiraDeTrabalho; }
    }
    private CarteiraDeTrabalho carteiraDeTrabalho;

    public string PisPasep
    {
      get { return pisPasep; }
      set { SetProperty("PisPasep", ref this.pisPasep, value); }
    }
    private string pisPasep = string.Empty;

    public DateTime DataDeAdmissão
    {
      get { return dataDeAdmissão; }
      set { SetProperty("DataDeAdmissão", ref this.dataDeAdmissão, value); }
    }
    private DateTime dataDeAdmissão = DateTime.MinValue;

    public DateTime DataDeDemissão
    {
      get { return dataDeDemissão; }
      set { SetProperty("DataDeDemissão", ref this.dataDeAdmissão, value); }
    }
    private DateTime dataDeDemissão = DateTime.MinValue;

    public decimal Salário
    {
      get { return salário; }
    }
    private decimal salário;    

    public Sindicato Sindicato
    {
      get { return sindicato; }
      set { sindicato = value; }
    }
    private Sindicato sindicato;

    #endregion

    #region Métodos --------------------------------------------------------------

    public override void GetObjectData(SerializationInfo info, StreamingContext context)
    {
      base.GetObjectData(info, context);
      info.AddValue("Salário", this.salário);
      info.AddValue("CarteiraDeTrabalho", this.carteiraDeTrabalho);
      info.AddValue("PisPasep", this.pisPasep);
      info.AddValue("DataDeAdmissão", this.dataDeAdmissão);
      info.AddValue("DataDeDemissão", this.dataDeDemissão);
    }

    public void AtribuirCarteiraDeTrabalho(string número, string série, string uf)
    {
      CarteiraDeTrabalho novaCarteira = new CarteiraDeTrabalho(this, número, série, uf);
      SetProperty("CarteiraDeTrabalho", ref this.carteiraDeTrabalho, novaCarteira);
    }

    public void AtribuirCarteiraDeTrabalho(string número)
    {
      this.AtribuirCarteiraDeTrabalho(número, string.Empty, string.Empty);
    }

    public void AlterarSalario(decimal novoSalario, string motivo)
    {
      this.AlterarSalario(novoSalario, DateTime.Now, motivo);
    }

    public void AlterarSalario(decimal novoSalario, DateTime dataDaAlteração, string motivo)
    {
      SetProperty("Salário", ref this.salário, novoSalario);

      if(this.CarteiraDeTrabalho != null)
      {
        CarteiraDeTrabalho.AlteraçãoSalarial alteração = new CarteiraDeTrabalho.AlteraçãoSalarial();
        alteração.NovoSalário = novoSalario;
        alteração.DataDaAlteração = dataDaAlteração;
        alteração.DataDaEfetivação = DateTime.Now;
        alteração.Motivo = motivo;
        this.CarteiraDeTrabalho.AlteraçõesSalariais.Add(alteração);
      }
    }

    #endregion
  }
}
